/***************************************************************************
 * Open Object Oriented ANSI C                                             *
 ***************************************************************************
 * Code given under the terms of GNU General Public Licence (GPLv3)        *
 * and without any waranties of any kind including but not limitative to   *
 * waranties on merchandability or any particular applications fitness.    *
 * For more information on GNU/GPL go on :                                 *
 * "http://www.gnu.org/copyleft/gpl.html"                                  *
 *                                                                         *
 * You are allowed to use it for any purposes in the terms of GNU/GPLv3    *
 * (or more).                                                              *
 * This text MUST stay in state on copyed sources (or sources using it)    *
 * and must not be altered.                                                *
 * You are allowed to add your name at the end of the Copylefs list.       *
 ***************************************************************************
 * Copylefts List :                                                        *
 ***************************************************************************
 * 2010-04-16 Patrick PIGNOL <pignol_patrick@hotmail.com> (Original)       *
 * (Type your name here if needed)                                         *
 ***************************************************************************/
#ifndef DELEGATE_H
#define DELEGATE_H

#define EVENTDELEGATE_TYPEID 10

typedef struct EventDelegate EventDelegate;
typedef struct EventDelegateVirtualTable EventDelegateVirtualTable;
typedef struct EventDelegateInterface EventDelegateInterface;

#include "Class.h"
#include "EventArgs.h"
#include "Event.h"

struct EventDelegateVirtualTable
{
    unsigned long int TypeID;
    EventDelegateInterface* Interface;
    ClassVirtualTable* AncestorTable;
    EventDelegateVirtualTable* InheritorTable;
    unsigned long int ReferenceCount;
    EventDelegate* (*new)(unsigned long pArgsCount, va_list* pParameters);
    EventDelegateVirtualTable* (*Initialize)(EventDelegate* this, unsigned long pArgsCount, va_list* pParameters);
    void (*Garbage)(EventDelegate* this);
    unsigned long int (*TypeOf)(EventDelegate* this);
    bool (*IsSameTypeThanTypeID)(EventDelegate* this, unsigned long int pTypeID);
    bool (*IsKindOfTypeID)(EventDelegate* this, unsigned long int pTypeID);
    bool (*IsSameTypeThan)(EventDelegate* this, Class* pSource);
    bool (*IsKindOf)(EventDelegate* this, Class* pSource);
};

struct EventDelegateInterface
{
    void (*Constructor)(EventDelegate* this, unsigned long int pArgsCount, va_list* pParameters);
    void (*Destructor)(EventDelegate* this);
    EventDelegate* (*Clone)(EventDelegate* this);
    void (*Handle)(EventDelegate* this, Class* pSender, EventArgs* pEventArgs);
};

struct EventDelegate
{
    EventDelegateVirtualTable* VirtualTable;
    void (*Constructor)(EventDelegate* this, unsigned long int pArgsCount, va_list* pParameters);
    void (*Destructor)(EventDelegate* this);
    EventDelegate* (*Clone)(EventDelegate* this);
    Class* aObserver;
    Event* aEvent;
    void (*aHandler)(Class* pObserver, Class* pSender, EventArgs* pEventArgs);
    void (*Handle)(EventDelegate* this, Class* pSender,EventArgs* pEventArgs);
};

EventDelegate* EventDelegateNew(unsigned long pArgsCount, va_list* pParameters);
EventDelegateVirtualTable* EventDelegateInitialize(EventDelegate* this, unsigned long pArgsCount, va_list* pParameters);
void EventDelegateConstructor(EventDelegate* this, unsigned long int pArgsCount, va_list* pParameters);
void EventDelegateDestructor(EventDelegate* this);
EventDelegate* EventDelegateClone(EventDelegate* this);
void (EventDelegateHandle)(EventDelegate* this, Class* pSender, EventArgs* pEventArgs);

#endif /* DELEGATE_H */
